package com.xgy.backend.service.impl;

import com.xgy.backend.dto.BoardKifuDto;
import com.xgy.backend.dto.ScreeningConditionDto;
import com.xgy.backend.mapper.Level0BoardMapper;
import com.xgy.backend.service.AsyncService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;

@Service
public class AsyncServiceImpl implements AsyncService {

    @Autowired
    Level0BoardMapper level0BoardMapper;

    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        swap(a,b);
        System.out.printf("main()a= "+a+"   ");
        System.out.println("main()b= "+b+"   ");
    }
    public static void swap(int a,int b){
        int temp = b;
        b = a;
        a = temp;
        System.out.printf("a= "+a+"   ");
        System.out.println("b= "+b);
    }
    @Async("asyncBoardServiceExecutor")
    @Override
    public CompletableFuture<List<BoardKifuDto>> executeBoardAsync(ScreeningConditionDto screeningCondition,int start, int end) {
        try {
            Integer moveNumFrom = screeningCondition.getMoveNum()!=null?Integer.valueOf((screeningCondition.getMoveNum().split("~")[0])):null;     //起始手数
            Integer moveNumTo = screeningCondition.getMoveNum()!=null?Integer.valueOf((screeningCondition.getMoveNum().split("~")[1])):null;       //最高手数
            Float blackWinRateFrom = screeningCondition.getBlackWinRate()!=null?Float.valueOf(((screeningCondition.getBlackWinRate().split("~")[0]))):null;  //起始黑方胜率
            Float blackWinRateTo = screeningCondition.getBlackWinRate()!=null?Float.valueOf(((screeningCondition.getBlackWinRate().split("~")[1]))):null;    //最高黑方胜率
            Integer blackScoreRegFrom = screeningCondition.getBlackScoreReg()!=null?Integer.valueOf((screeningCondition.getBlackScoreReg().split("~")[0])):null;//起始黑方目差
            Integer blackScoreRegTo = screeningCondition.getBlackScoreReg()!=null?Integer.valueOf((screeningCondition.getBlackScoreReg().split("~")[1])):null;  //最高黑方目差
            Double targetBlackAnFrom = screeningCondition.getTargetBlackAn()!=null?Double.valueOf(screeningCondition.getTargetBlackAn().split("~")[0]):null;  //起始目标黑棋子An
            Double targetBlackAnTo= screeningCondition.getTargetBlackAn()!=null?Double.valueOf(screeningCondition.getTargetBlackAn().split("~")[1]):null;     //最高目标黑棋子An
            Double targetWhiteAnFrom = screeningCondition.getTargetWhiteAn()!=null?Double.valueOf(screeningCondition.getTargetWhiteAn().split("~")[0]):null;  //起始目标白棋子An
            Double targetWhiteAnTo= screeningCondition.getTargetWhiteAn()!=null?Double.valueOf(screeningCondition.getTargetWhiteAn().split("~")[1]):null;     //最高目标白棋子An
            Double targetBlackCrossAnFrom = screeningCondition.getTargetBlackCrossAn()!=null?Double.valueOf(screeningCondition.getTargetBlackCrossAn().split("~")[0]):null;  //起始目标黑交叉点An
            Double targetBlackCrossAnTo= screeningCondition.getTargetBlackCrossAn()!=null?Double.valueOf(screeningCondition.getTargetBlackCrossAn().split("~")[1]):null;     //最高目标黑交叉点An
            Double targetWhiteCrossAnFrom = screeningCondition.getTargetWhiteCrossAn()!=null?Double.valueOf(screeningCondition.getTargetWhiteCrossAn().split("~")[0]):null;  //起始目标白交叉点An
            Double targetWhiteCrossAnTo= screeningCondition.getTargetWhiteCrossAn()!=null?Double.valueOf(screeningCondition.getTargetWhiteCrossAn().split("~")[1]):null;     //最高目标白交叉点An
            Integer targetBlackNumFrom = screeningCondition.getTargetBlackNum()!=null?Integer.valueOf((screeningCondition.getTargetBlackNum().split("~")[0])):null;//起始目标黑棋子个数
            Integer targetBlackNumTo = screeningCondition.getTargetBlackNum()!=null?Integer.valueOf((screeningCondition.getTargetBlackNum().split("~")[1])):null;  //最高目标黑棋子个数
            Integer targetWhiteNumFrom = screeningCondition.getTargetWhiteNum()!=null?Integer.valueOf((screeningCondition.getTargetWhiteNum().split("~")[0])):null;//起始目标白棋子个数
            Integer targetWhiteNumTo = screeningCondition.getTargetWhiteNum()!=null?Integer.valueOf((screeningCondition.getTargetWhiteNum().split("~")[1])):null;  //最高目标白棋子个数
            Integer targetBlackCrossNumFrom = screeningCondition.getTargetBlackCrossNum()!=null?Integer.valueOf((screeningCondition.getTargetBlackCrossNum().split("~")[0])):null;//起始目标黑交叉点个数
            Integer targetBlackCrossNumTo = screeningCondition.getTargetBlackCrossNum()!=null?Integer.valueOf((screeningCondition.getTargetBlackCrossNum().split("~")[1])):null;  //最高目标黑交叉点个数
            Integer targetWhiteCrossNumFrom = screeningCondition.getTargetWhiteCrossNum()!=null?Integer.valueOf((screeningCondition.getTargetWhiteCrossNum().split("~")[0])):null;//起始目标白交叉点个数
            Integer targetWhiteCrossNumTo = screeningCondition.getTargetWhiteCrossNum()!=null?Integer.valueOf((screeningCondition.getTargetWhiteCrossNum().split("~")[1])):null;  //最高目标白交叉点个数
            Integer targetChessSubFrom = screeningCondition.getTargetChessSub()!=null?Integer.valueOf((screeningCondition.getTargetChessSub().split("~")[0])):null;//起始目标棋子个数差
            Integer targetChessSubTo = screeningCondition.getTargetChessSub()!=null?Integer.valueOf((screeningCondition.getTargetChessSub().split("~")[1])):null;  //最高目标棋子个数差
            Integer targetChessSumFrom = screeningCondition.getTargetChessSum()!=null?Integer.valueOf((screeningCondition.getTargetChessSum().split("~")[0])):null;//起始目标棋子个数和
            Integer targetChessSumTo = screeningCondition.getTargetChessSum()!=null?Integer.valueOf((screeningCondition.getTargetChessSum().split("~")[1])):null;  //最高目标棋子个数和
            Integer targetCrossSubFrom = screeningCondition.getTargetCrossSub()!=null?Integer.valueOf((screeningCondition.getTargetCrossSub().split("~")[0])):null;//起始目标交叉点个数差
            Integer targetCrossSubTo = screeningCondition.getTargetCrossSub()!=null?Integer.valueOf((screeningCondition.getTargetCrossSub().split("~")[1])):null;  //最高目标交叉点个数差
            Integer targetCrossSumFrom = screeningCondition.getTargetCrossSum()!=null?Integer.valueOf((screeningCondition.getTargetCrossSum().split("~")[0])):null;//起始目标交叉点个数和
            Integer targetCrossSumTo = screeningCondition.getTargetCrossSum()!=null?Integer.valueOf((screeningCondition.getTargetCrossSum().split("~")[1])):null;  //最高目标交叉点个数和
            Integer targetCrossChessSumFrom = screeningCondition.getTargetCrossChessSum()!=null?Integer.valueOf((screeningCondition.getTargetCrossChessSum().split("~")[0])):null;//起始目标交叉点和棋子个数和
            Integer targetCrossChessSumTo = screeningCondition.getTargetCrossChessSum()!=null?Integer.valueOf((screeningCondition.getTargetCrossChessSum().split("~")[1])):null;  //最高目标交叉点和棋子个数和
            //初级筛选
            List<BoardKifuDto> list = level0BoardMapper.selectByIdRange(moveNumFrom,moveNumTo,
                    blackWinRateFrom,blackWinRateTo,
                    blackScoreRegFrom,blackScoreRegTo,
                    start,end);

            List<BoardKifuDto> res = new ArrayList<>();
            //高级筛选
            for(BoardKifuDto bk:list){
                //每个位置对应是否落子，下标从1开始
                boolean[][] vis = new boolean[20][20];
                String sgfMoves = bk.getSgfMoves();//棋盘手顺
                String area = bk.getArea();//棋盘361个点的an值

                int targetBlackAnCnt = 0; //黑棋中an值满足targetBlackAnFrom ~ targetBlackAnTo的数量
                int targetWhiteAnCnt = 0; //白棋中an值满足targetWhiteAnFrom ~ targetWhiteAnTo的数量
                int targetBlackCrossAnCnt = 0;//黑交叉点中an值满足targetBlackCrossAnFrom ~ targetBlackCrossAnTo的数量
                int targetWhiteCrossAnCnt = 0;//白交叉点中an值满足targetWhiteCrossAnFrom ~ targetWhiteCrossAnTo的数量

                //逻辑复原棋盘(下标从1开始)，得到targetBlackAnCnt、targetWhiteAnCnt、targetBlackCrossAnCnt、targetWhiteCrossAnCnt
                int k = 0;
                for(int i=0;i<sgfMoves.length();i+=2){
                    //跳过字母 'i'，例如字母j，原本对应位置j-a+1 = 10，但i不存在，它应该在下标9
                    int x = sgfMoves.charAt(i)-'a'+1<9 ? sgfMoves.charAt(i)-'a'+1 : sgfMoves.charAt(i)-'a';//棋盘行数
                    int y = sgfMoves.charAt(i+1)-'a'+1<9 ? sgfMoves.charAt(i+1)-'a'+1 : sgfMoves.charAt(i+1)-'a';//棋盘列数

                    //对应位置的An值  area的小写字母代表负数/偏黑，大写字母代表正数/偏白
                    char c = area.charAt((x - 1) * 19 + y-1);  //棋盘行列数确定的点对应area 361个字符中的1个字符
                    int operator = Character.isLowerCase(c)? -1:1;//正负号
                    c = Character.toLowerCase(c);//统一转小写
                    double curAnFrom = operator *(c-'a') * 0.05;
                    double curAnTo = operator * (c-'a'+1) * 0.05;
                    //黑棋落子
                    if(targetBlackAnFrom!=null && targetBlackAnTo!=null && k%2==0 && curAnFrom >= targetBlackAnFrom && curAnTo<= targetBlackAnTo)
                        targetBlackAnCnt++;
                    //白棋落子
                    else if(targetWhiteAnFrom!=null && targetWhiteAnTo!=null && k%2==1 && curAnFrom >= targetWhiteAnFrom && curAnTo<= targetWhiteAnTo)
                        targetWhiteAnCnt++;

                    vis[x][y] = true;//已落子，同一个位置如果重复落黑子/白子，也不会遗漏双方An个数
                    k++;
                }

                //单独处理交叉点
                for(int i=1;i<20;i++){
                    for(int j=1;j<20;j++){
                        if(!vis[i][j]){
                            //对应位置的An值  area的小写字母代表负数/偏黑，大写字母代表正数/偏白
                            char c = area.charAt((i - 1) * 19 + j-1);  //棋盘行列数确定的点对应area 361个字符中的1个字符
                            int operator = Character.isLowerCase(c)? -1:1;//正负号
                            c = Character.toLowerCase(c);//统一转小写
                            double curAnFrom = operator *(c-'a') * 0.05;
                            double curAnTo = operator * (c-'a'+1) * 0.05;
                            //黑交叉点：无落子 area字母为小写(An值为负)
                            if(targetBlackCrossAnFrom!=null && targetBlackCrossAnTo!=null && operator==-1 && curAnFrom >= targetBlackCrossAnFrom && curAnTo<= targetBlackCrossAnTo){
                                targetBlackCrossAnCnt++;
                            }
                            //白交叉点：无落子 area字母为大写(An值为正)
                            else if(targetWhiteCrossAnFrom!=null && targetWhiteCrossAnTo!=null && operator==1 && curAnFrom >= targetWhiteCrossAnFrom && curAnTo<= targetWhiteCrossAnTo){
                                targetWhiteCrossAnCnt++;
                            }
                        }
                    }
                }

                //目标黑棋子个数：筛选targetBlackNumFrom ~ targetBlackNumTo
                if(targetBlackNumFrom!=null && targetBlackNumTo!=null && (targetBlackAnCnt<targetBlackNumFrom || targetBlackAnCnt>targetBlackNumTo))
                    continue;
                //目标白棋子个数：筛选targetWhiteNumFrom ~ targetWhiteNumTo
                if(targetWhiteNumFrom!=null && targetWhiteNumTo!=null && (targetWhiteAnCnt<targetWhiteNumFrom || targetWhiteAnCnt>targetWhiteNumTo))
                    continue;
                //目标黑交叉点个数：满足targetBlackCrossNumFrom ~ targetBlackCrossNumTo
                if(targetBlackCrossNumFrom!=null && targetBlackCrossNumTo!=null  && (targetBlackCrossAnCnt<targetBlackCrossNumFrom || targetBlackCrossAnCnt>targetBlackCrossNumTo))
                    continue;
                //目标白交叉点个数：筛选是否满足targetWhiteCrossNumFrom ~ targetWhiteCrossNumTo
                if(targetWhiteCrossNumFrom!=null && targetWhiteCrossNumTo!=null  && (targetWhiteCrossAnCnt<targetWhiteCrossNumFrom || targetWhiteCrossAnCnt>targetWhiteCrossNumTo))
                    continue;
                //目标棋子个数差：筛选(targetBlackAnCnt-targetWhiteAnCnt) 是否满足targetChessSubFrom ~ targetChessSubTo
                if(targetChessSubFrom!=null && targetChessSubTo!=null && ((targetBlackAnCnt-targetWhiteAnCnt)<targetChessSubFrom || (targetBlackAnCnt-targetWhiteAnCnt)>targetChessSubTo))
                    continue;
                //目标棋子个数和：筛选(targetBlackAnCnt+targetWhiteAnCnt) 是否满足targetChessSumFrom ~ targetChessSumTo
                if(targetChessSumFrom!=null && targetChessSumTo!=null && ((targetBlackAnCnt+targetWhiteAnCnt)<targetChessSumFrom || (targetBlackAnCnt+targetWhiteAnCnt)>targetChessSumTo))
                    continue;
                //目标交叉点个数差：筛选(targetBlackCrossAnCnt-targetWhiteCrossAnCnt) 是否满足targetCrossSubFrom ~ targetCrossSubTo
                if(targetCrossSubFrom!=null && targetCrossSubTo!=null && ((targetBlackCrossAnCnt-targetWhiteCrossAnCnt)<targetCrossSubFrom
                        || (targetBlackCrossAnCnt-targetWhiteCrossAnCnt)>targetCrossSubTo))
                    continue;
                //目标交叉点个数和：筛选(targetBlackCrossAnCnt+targetWhiteCrossAnCnt) 是否满足targetCrossSumFrom ~ targetCrossSumTo
                if(targetCrossSumFrom!=null && targetCrossSumTo!=null && ((targetBlackCrossAnCnt+targetWhiteCrossAnCnt)<targetCrossSumFrom
                        || (targetBlackCrossAnCnt+targetWhiteCrossAnCnt)>targetCrossSumTo))
                    continue;
                //目标交叉点和棋子个数和：筛选(targetBlackAnCnt+targetWhiteAnCnt) +  (targetBlackCrossAnCnt+targetWhiteCrossAnCnt)是否满足targetCrossChessSumFrom ~ targetCrossChessSumTo
                if(targetCrossChessSumFrom!=null && targetCrossChessSumTo!=null && ((targetBlackAnCnt+targetWhiteAnCnt+targetBlackCrossAnCnt+targetWhiteCrossAnCnt)<targetCrossChessSumFrom
                        || (targetBlackAnCnt+targetWhiteAnCnt+targetBlackCrossAnCnt+targetWhiteCrossAnCnt)>targetCrossChessSumTo))
                    continue;
                res.add(bk);
            }

            return CompletableFuture.completedFuture(res);
        } catch (Exception e) {
            e.printStackTrace();
            // 处理异常情况
            return CompletableFuture.completedFuture(Collections.emptyList()); // 返回一个空列表或其他错误处理方式
        }
    }
}
